/*
 * Statistics.java
 *
 * Created on May 24, 2008, 2:51 PM
 */
package p2p.simulator.gui;

import java.awt.Rectangle;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import p2p.simulator.Simulator;

/**
 *
 * @author  papalukg
 */
public class Statistics extends javax.swing.JPanel {

    private Simulator S;
    private StatusBar statBar;

    /** Creates new form Statistics */
    public Statistics() {
        initComponents();
    }

    public Statistics(Simulator S, StatusBar statBar) {
        this.S = S;
        this.statBar = statBar;
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        peersLabel = new javax.swing.JLabel();
        keysLabel = new javax.swing.JLabel();
        rtSizeLabel = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        levelsLabel = new javax.swing.JLabel();
        operationsLabel = new javax.swing.JLabel();
        jSeparator3 = new javax.swing.JSeparator();
        jLabel14 = new javax.swing.JLabel();
        insertLabel = new javax.swing.JLabel();
        jLabel16 = new javax.swing.JLabel();
        lookupLabel = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        deleteLabel = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        loadButton = new javax.swing.JButton();
        reportButton = new javax.swing.JButton();

        jLabel1.setText("Overview");

        jLabel2.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel2.setText("Cluster Peers");

        jLabel3.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel3.setText("Key Space");

        jLabel4.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel4.setText("Average Routing Table Size");

        peersLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        peersLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        peersLabel.setText("0");
        peersLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        keysLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        keysLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        keysLabel.setText("0");
        keysLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        rtSizeLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        rtSizeLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        rtSizeLabel.setText("0");
        rtSizeLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        jLabel8.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel8.setText("Average Cluster Peer Load");

        jLabel9.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel9.setText("Total Operations");

        levelsLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        levelsLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        levelsLabel.setText("0");
        levelsLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        operationsLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        operationsLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        operationsLabel.setText("0");
        operationsLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        jSeparator3.setForeground(new java.awt.Color(153, 166, 191));

        jLabel14.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel14.setText("Average Insertion Path");

        insertLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        insertLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        insertLabel.setText("0");
        insertLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        jLabel16.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel16.setText("Average Lookup Path");

        lookupLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        lookupLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        lookupLabel.setText("0");
        lookupLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        jLabel18.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel18.setText("Average Deletion Path");

        deleteLabel.setFont(new java.awt.Font("Dialog", 0, 12));
        deleteLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        deleteLabel.setText("0");
        deleteLabel.setPreferredSize(new java.awt.Dimension(100, 15));

        jLabel10.setText("Load Balance");

        jLabel13.setFont(new java.awt.Font("Dialog", 0, 12));
        jLabel13.setText("Messages Per Cluster Peer");

        loadButton.setFont(new java.awt.Font("Dialog", 0, 12));
        loadButton.setText("plot");
        loadButton.setMargin(new java.awt.Insets(2, 5, 2, 5));
        loadButton.setPreferredSize(new java.awt.Dimension(34, 24));
        loadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadButtonActionPerformed(evt);
            }
        });

        reportButton.setFont(new java.awt.Font("Dialog", 0, 12));
        reportButton.setText("report");
        reportButton.setMargin(new java.awt.Insets(2, 5, 2, 5));
        reportButton.setPreferredSize(new java.awt.Dimension(34, 24));
        reportButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                reportButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(12, 12, 12)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel3)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 206, Short.MAX_VALUE)
                                        .addComponent(keysLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel2)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 189, Short.MAX_VALUE)
                                        .addComponent(peersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel4)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 107, Short.MAX_VALUE)
                                        .addComponent(rtSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel9)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 169, Short.MAX_VALUE)
                                .addComponent(operationsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addComponent(jLabel8)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 112, Short.MAX_VALUE)
                                .addComponent(levelsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jSeparator3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 377, Short.MAX_VALUE)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGap(12, 12, 12)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel14)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 136, Short.MAX_VALUE)
                                        .addComponent(insertLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                        .addComponent(jLabel16)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 143, Short.MAX_VALUE)
                                        .addComponent(lookupLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGroup(layout.createSequentialGroup()
                                        .addComponent(jLabel18)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 138, Short.MAX_VALUE)
                                        .addComponent(deleteLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(12, 12, 12)
                                .addComponent(jLabel13)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 165, Short.MAX_VALUE)
                                .addComponent(loadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jLabel10)))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(reportButton, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(peersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(keysLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(rtSizeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(levelsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(operationsLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lookupLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel16))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel14)
                    .addComponent(insertLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel18)
                    .addComponent(deleteLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 9, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel13))
                    .addComponent(loadButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(105, 105, 105)
                .addComponent(reportButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
        // TODO add your handling code here:
        java.awt.EventQueue.invokeLater(new Runnable() {

            private Plot loadPlot;

            public void run() {
                loadPlot = new Plot(S.getLoadFt(), "Load Performance", "Messages/Cluster Peer");
                loadPlot.setVisible(true);
            }
        });
}//GEN-LAST:event_loadButtonActionPerformed

private void reportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reportButtonActionPerformed
// TODO add your handling code here:


    java.awt.EventQueue.invokeLater(new Runnable() {

        public void run() {
            String filename = (new SaveDialogWindow("txt")).getFilename();
            
            if (filename == null)
                return;
            
            statBar.updateStatusLabel("Publishing Report...");
            S.publishReport(filename);
            statBar.updateStatusLabel("Done");
        }
    });

}//GEN-LAST:event_reportButtonActionPerformed
    
    public void updateStatistics() {
        
        if (S.getNofPeers() == 0)
            return;
        peersLabel.setText(""+S.getNofPeers());
        keysLabel.setText(""+S.getNofKeys());
        rtSizeLabel.setText(""+getAvgMetric(S.getRoutingFt()));
        levelsLabel.setText(""+getAvgMetric(S.getLoadFt()));
        operationsLabel.setText(""+S.getOperations());
        lookupLabel.setText(""+getAvgMetric(S.getLookupFt()));
        insertLabel.setText(""+getAvgMetric(S.getInsertFt()));
        deleteLabel.setText(""+getAvgMetric(S.getDeleteFt()));
        
        Rectangle stats = super.getBounds();
        stats.x = 0;
        stats.y = 0;
        super.paintImmediately(stats);
        
    }
    
    private double getAvgMetric(HashMap hm) {
    
        int n, freq, min, max;
        double avrg, sum, total;
        boolean firstIteration;
        Iterator keyIterator;
        String key, frequency;
        Set keys;
        String str;
        
        keys = hm.keySet();
        keyIterator = keys.iterator();
        avrg = total = sum = min = max = n = 0;
        firstIteration = true;
        
        str = "";
        
        while (keyIterator.hasNext()) {
            key = (String)keyIterator.next();
            frequency = hm.get(key).toString();
            str += "   "+key+"           "+frequency+"\n";
            try {
                n = Integer.parseInt(key);
                freq = Integer.parseInt(frequency);
                sum += n*freq;
                total += freq;
            }
            catch(NumberFormatException e) {
                e.printStackTrace();
            }
            
            // Find the minimum and maximum path length
            if (firstIteration) {
                firstIteration = false;
                min = max = n;
            } 
            else {
                if (n < min)
                    min = n;
                if (n > max)
                    max = n;
            }
        }
        
        // Calculate the average path length
        avrg = sum / total;
        
        return avrg;
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel deleteLabel;
    private javax.swing.JLabel insertLabel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JLabel keysLabel;
    private javax.swing.JLabel levelsLabel;
    private javax.swing.JButton loadButton;
    private javax.swing.JLabel lookupLabel;
    private javax.swing.JLabel operationsLabel;
    private javax.swing.JLabel peersLabel;
    private javax.swing.JButton reportButton;
    private javax.swing.JLabel rtSizeLabel;
    // End of variables declaration//GEN-END:variables
    
}
